﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Leadtools;
using Leadtools.Codecs;
using Leadtools.ImageProcessing;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;



namespace ImageCom.LeadtoolEx
{
    public class LDEx : IDisposable
    {
        static LDEx()
        {
            RasterCodecs.Startup();
            _codecs = new RasterCodecs();
        }

        protected static RasterCodecs _codecs;
        protected const string Jpgflag = ".JPG.JPEG.PSD.TIF";

        public void Dispose()
        {
            RasterCodecs.Shutdown();
        }

        public static Image ToMaxSimpleGrayImage(string inFolder, int w = 600, int h = 600)
        {
            string filePath = MaxImagePath(inFolder);
            if (string.IsNullOrEmpty(filePath))
            {
                return null;
            }
        
            RasterImage image = _codecs.Load(filePath);
            ResizeImage(image, new Size(w, h));
            ToSimpleGray2(ref image);
            Image bitmap = image.ConvertToGdiPlusImage();
            //var intPtr=image.ToDib(RasterConvertToDibType.BitmapInfoHeader);
            //Bitmap bitmap = new Bitmap(image.Width, image.Height, 4, PixelFormat.Format24bppRgb, intPtr);
            return bitmap;
        }
        public static Image ToMaxSimpleGrayImage(int w = 600, int h = 600, params string[] inFolder)
        {
            string filePath = MaxImagePath(inFolder);

         
            if (string.IsNullOrEmpty(filePath))
            {
                return null;
            }
            RasterImage image = _codecs.Load(filePath);
            ResizeImage(image, new Size(w, h));
            ToSimpleGray2(ref image);
            Image bitmap = image.ConvertToGdiPlusImage();
            //var intPtr=image.ToDib(RasterConvertToDibType.BitmapInfoHeader);
            //Bitmap bitmap = new Bitmap(image.Width, image.Height, 4, PixelFormat.Format24bppRgb, intPtr);
            return bitmap;
        }
        public static Image ToSimpleGrayImage(string inPath, int w = 600, int h = 600)
        {

            RasterImage image = _codecs.Load(inPath);
            ResizeImage(image, new Size(w, h));
            ToSimpleGray(ref image);
            Image bitmap = image.ConvertToGdiPlusImage();
            //var intPtr=image.ToDib(RasterConvertToDibType.BitmapInfoHeader);
            //Bitmap bitmap = new Bitmap(image.Width, image.Height, 4, PixelFormat.Format24bppRgb, intPtr);
            return bitmap;
        }

        /// <summary>
        /// 获取路径中 最大的图
        /// </summary>
        /// <param name="inFolder"></param>
        /// <returns></returns>
        public static string MaxImagePath(params string[] inFolder)
        {
            string path = "";
            List<string> filepathList = new List<string>();
            try
            {
                foreach (string folder in inFolder)
                {
                    if (Directory.Exists(folder))
                    {
                        foreach (string filePath in Directory.GetFiles(folder, "*.*", SearchOption.AllDirectories))
                        {
                            //string array = filePath;
                            //string[] sArray = array.Split('.');
                            //if (sArray[4] == "jpg" || sArray[4] == "jpeg")
                            //{
                            string extName = Path.GetExtension(filePath);
                            
                            if(!string.IsNullOrEmpty(extName)&&Jpgflag.Contains(extName.ToUpper()))
                                filepathList.Add(filePath);
                            }
                        }
                    }
                

                double aresPhoto = 0;

                foreach (string filePath in filepathList)
                {
                    if (string.IsNullOrEmpty(path))
                    {
                        path = filePath;
                    }

                    using (CodecsImageInfo info = _codecs.GetInformation(filePath, true))
                    {
                        //ieImage.LoadImageInfo(filePath);
                        //IOParams ioParams = ieImage.IOParams;
                        int vHeight = info.Height;
                        int vWidth = info.Width;
                        if (vHeight * vWidth > aresPhoto)
                        {
                            aresPhoto = vHeight * vWidth;
                            path = filePath;
                        }
                    }

                }


            }
            catch (Exception ex)
            {
                throw new Exception("获取最大文件失败" + ex.ToString());

            }
            finally
            {

                // ieImagePool.CheckIn(ieImage);
            }

            return path;
        }

        public static void ToSimpleGrayImage(string inPath, string outpath)
        {

            RasterImage image = _codecs.Load(inPath);
            ToSimpleGray(ref image);
            _codecs.Save(image, outpath, RasterImageFormat.Jpeg, 24);

        }


        public static RasterImage CreateImage(string inpath)
        {
            RasterImage image = _codecs.Load(inpath);
            return image;
        }

        public static RasterImage CreateImageStream(string inpath)
        {
            RasterImage image = null;
            using (FileStream fileStream = new FileStream(inpath, FileMode.Open))
            {
                image = _codecs.Load(fileStream);
            }

            return image;
        }

        public static bool SaveRasteImae(RasterImage inImage, string inSavePath)
        {

            _codecs.Save(inImage, inSavePath, RasterImageFormat.Jpeg, 24);
            return File.Exists(inSavePath);
        }

        public static void ToSimpleGray(ref RasterImage image)
        {
            int BitsPerPixel = 1;
            ColorResolutionCommand command = new ColorResolutionCommand(ColorResolutionCommandMode.InPlace,
                BitsPerPixel, RasterByteOrder.Rgb, RasterDitheringMethod.Jarvis,
                ColorResolutionCommandPaletteFlags.Fixed, null);

            command.Run(image);
        }
        public static void ToSimpleGray2(ref RasterImage image)
        {
            //int BitsPerPixel = 1;
            image.XResolution = 150;
            image.YResolution = 150;
            GrayscaleCommand command = new GrayscaleCommand();
            command.BitsPerPixel = 8;
            command.Run(image);

           // command.Run(image);
        }
        /// <summary>
        /// 裁切尺寸单位像素
        /// </summary>
        /// <param name="srcImage"></param>
        /// <param name="size"></param>
        protected static void ResizeImage(RasterImage srcImage, Size size)
        {
            SizeCommand command = new SizeCommand();

            float wScloar = srcImage.Width / (float)size.Width;
            float hScloar = srcImage.Height / (float)size.Height;
            float scloar = wScloar >= hScloar ? wScloar : hScloar;
            Size factSize = new Size(0, 0);

            int w = Convert.ToInt32(srcImage.Width / scloar);
            int h = Convert.ToInt32(srcImage.Height / scloar);
            //factSize=new Size(w,h);
            command.Height = h;
            command.Width = w;
            command.Flags = RasterSizeFlags.None;
            command.Run(srcImage);
        }

        private static string CurrPath(string folderName)
        {
            string path = Path.Combine(System.Environment.CurrentDirectory, folderName);
            return path;
        }

        public static RasterImage CreateImageFromDIB(DiBImageInfo intPtr)
        {
            RasterImage image = new RasterImage(RasterMemoryFlags.Conventional,
                intPtr.width,
                intPtr.heigth, 24, RasterByteOrder.Bgr, RasterViewPerspective.LeftBottom, null, IntPtr.Zero, 0);
            return image;
        }

        /// <summary>
        /// 获取文件夹下所有照片的信息
        /// </summary>
        /// <param name="inFolder"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        public static void GetShortImageInfo(string inFolder, List<FileSizeInfo> list, bool searchChildFolder = false)
        {

            //DirectoryInfo diroot = new DirectoryInfo(inFolder);
            if (Directory.Exists(inFolder))
            {
                foreach (string fileName in Directory.GetFiles(inFolder))
                {
                    var pinfo = GetFileSizeInfo(fileName);
                    if (list == null)
                    {
                        list = new List<FileSizeInfo>();
                    }
                    else
                    {
                        if (pinfo.Width > 0)
                        {
                            list.Add(pinfo);
                        }
                    }
                }
                if (searchChildFolder)
                {
                    foreach (string dirSub in Directory.GetDirectories(inFolder).Where(s => !s.Contains("已下单")))
                    {
                        GetShortImageInfo(dirSub, list, searchChildFolder);
                    }
                }
            }
        }
        protected static RasterImage CombineTwoImage(RasterImage srcImage1, RasterImage srcImage2, int dictDirection, int dpi = 254)
        {
            RasterImage destImage = null;
            ;
            int height = 0;
            int width = 0;
            try
            {
                if (dictDirection == 1)
                {
                    if (srcImage1.Height >= srcImage2.Height)
                    {
                        height = srcImage1.Height;
                    }
                    else
                    {
                        height = srcImage2.Height;
                    }
                    //destImage = new RasterImage(
                    //    RasterMemoryFlags.Tiled,
                    //    srcImage1.Width + srcImage2.Width,
                    //    height,
                    //    24,
                    //    RasterByteOrder.Bgr,
                    //    RasterViewPerspective.BottomLeft,
                    //    null,
                    //    IntPtr.Zero,
                    //    0);
                    destImage = CreateRasterImage(new Size(srcImage1.Width + srcImage2.Width, height));
                    destImage.XResolution = destImage.YResolution = dpi;
                    System.Drawing.Rectangle rc1 = new Rectangle(0, 0, srcImage1.Width, srcImage1.Height);
                    System.Drawing.Rectangle rc2 = new Rectangle(srcImage1.Width, 0, srcImage2.Width, srcImage2.Height);
                    CombineFastCommand cfctop = new CombineFastCommand();
                    //cfctop.DestinationRectangle = new Rectangle(180, 0, boardPointInfoImage.Width, boardPointInfoImage.Height);
                    destImage.XResolution = srcImage1.XResolution;
                    destImage.YResolution = srcImage1.YResolution;
                    cfctop.SourcePoint = Point.Empty;
                    cfctop.Flags = CombineFastCommandFlags.OperationAdd | CombineFastCommandFlags.Destination0;
                    cfctop.DestinationImage = destImage;
                    cfctop.DestinationRectangle = rc1;
                    cfctop.Run(srcImage1);
                    cfctop.DestinationRectangle = rc2;
                    cfctop.Run(srcImage2);
                }
                else
                {
                    if (srcImage1.Width >= srcImage2.Width)
                    {
                        width = srcImage1.Width;
                    }
                    else
                    {
                        width = srcImage2.Width;
                    }
                    //destImage = new RasterImage(
                    //    RasterMemoryFlags.Tiled,
                    //    width,
                    //    srcImage1.Height + srcImage2.Height,
                    //    24,
                    //    RasterByteOrder.Bgr,
                    //    RasterViewPerspective.BottomLeft,
                    //    null,
                    //    IntPtr.Zero,
                    //    0);
                    destImage = CreateRasterImage(new Size(width, srcImage1.Height + srcImage2.Height));
                    destImage.XResolution = destImage.YResolution = dpi;
                    System.Drawing.Rectangle rc1 = new Rectangle(0, 0, srcImage1.Width, srcImage1.Height + srcImage2.Height);
                    System.Drawing.Rectangle rc2 = new Rectangle(0, srcImage1.Height, srcImage2.Width, srcImage2.Height);
                    CombineFastCommand cfctop = new CombineFastCommand();
                    //cfctop.DestinationRectangle = new Rectangle(180, 0, boardPointInfoImage.Width, boardPointInfoImage.Height);
                    destImage.XResolution = srcImage1.XResolution;
                    destImage.YResolution = srcImage1.YResolution;
                    cfctop.SourcePoint = Point.Empty;
                    cfctop.Flags = CombineFastCommandFlags.OperationAdd | CombineFastCommandFlags.Destination0;
                    cfctop.DestinationImage = destImage;
                    cfctop.DestinationRectangle = rc1;
                    cfctop.Run(srcImage1);
                    cfctop.DestinationRectangle = rc2;
                    cfctop.Run(srcImage2);
                }
                return destImage;

            }
            catch (Exception)
            {

                throw;
            }
        }
        protected static RasterImage GenerateTags(string inPhotoContent, int inWidthPix, int inHeightMm = 3, int inDpi = 254, bool isVertical = true, Font barcodeFont = null, Font textFont = null, int offset = 0)
        {


            if (textFont == null)
            {
                textFont = new Font("微软雅黑", 8);
            }


            //Font barcodeFont
            RasterImage destImage = null;
            int pixHeight = (Int32)(inHeightMm / 2.54 / 10 * inDpi);
            int pixWidth = inWidthPix;

            destImage = CreateRasterImage(new Size(pixWidth, pixHeight));
            Graphics gDraw = destImage.CreateGdiPlusGraphics().Graphics;//用来打印条码和文字

            // string code128 = BarcodeConverter.ConvertToCode128(orderproductId);            \


            Rectangle rcFont = new Rectangle(20, -5, destImage.Width, pixHeight);
            StringFormat sf = new StringFormat();
            sf.Alignment = StringAlignment.Near;
            sf.LineAlignment = StringAlignment.Near;

            gDraw.DrawString(inPhotoContent, textFont, new SolidBrush(Color.Black), rcFont, sf);
            ColorResolutionCommand command = new ColorResolutionCommand(ColorResolutionCommandMode.InPlace, 24, RasterByteOrder.Bgr,
                                                               RasterDitheringMethod.None, ColorResolutionCommandPaletteFlags.Optimized, null);
            command.Run(destImage);//处理一遍条码和文字


            return destImage;
        }
        /// <summary>
        /// 获取文件的信息
        /// </summary>
        /// <param name="inFilePath"></param>
        /// <returns></returns>
        public static FileSizeInfo GetFileSizeInfo(string inFilePath)
        {
            FileSizeInfo info = new FileSizeInfo();
            if (File.Exists(inFilePath))
            {
                FileInfo fileName = new FileInfo(inFilePath);
                if (Jpgflag.Contains(fileName.Extension.ToUpper()))
                {
                    CodecsImageInfo imgInfo = null;
                    try
                    {
                        imgInfo = _codecs.GetInformation(fileName.FullName, true);
                    }
                    catch (Exception)
                    {

                    }
                    if (imgInfo != null)
                    {
                        info = new FileSizeInfo(imgInfo.Width, imgInfo.Height,
                            imgInfo.XResolution, imgInfo.YResolution, fileName.FullName);
                        info.FileName = fileName.Name;
                    }
                }
            }
            return info;
        }
        /// <summary>
        /// 创建空图，size像素值
        /// </summary>
        /// <param name="size"></param>
        /// <param name="dpi"></param>
        /// <param name="inR"></param>
        /// <param name="inG"></param>
        /// <param name="inB"></param>
        /// <returns></returns>
        protected static RasterImage CreateRasterImage(Size size, int dpi = 254, int inR = 255, int inG = 255, int inB = 255)
        {

            try
            {
                RasterImage destImage = new RasterImage(
                                 RasterMemoryFlags.Tiled,
                                    size.Width,
                                     size.Height,
                                     24,
                                     RasterByteOrder.Bgr,
                                     RasterViewPerspective.BottomLeft,
                                     null,
                                     IntPtr.Zero,
                                     0);
                destImage.XResolution = destImage.YResolution = dpi;
                destImage.OriginalFormat = RasterImageFormat.Jpeg;
                FillCommand fcommand = new FillCommand();

                fcommand.Color = new RasterColor(inR, inG, inB);
                fcommand.Run(destImage);

                return destImage;

            }
            catch (Exception)
            {

                throw;
            }
        }
        /// <summary>
        /// 旋转图片
        /// </summary>
        /// <param name="image"></param>
        /// <param name="angle"></param>
        protected static void RotateImage(RasterImage image, int angle)
        {
            //smallPicImage.c
            RotateCommand rc = new RotateCommand();
            rc.Angle = angle * 100;
            rc.FillColor = new RasterColor(255, 255, 255);
            rc.Flags = RotateCommandFlags.Resize | RotateCommandFlags.Bicubic;
            rc.Run(image);
        }
        public static string CombinTwoImageFromFile(List<FileSizeInfo> inList, bool deleteSrcFile = true)
        {
            var first = CreateImageWithFlag(inList[0]);
            var seond = CreateImageWithFlag(inList[1]);


            var destImage = CombineTwoImage(first, seond, 1);

            string folder = Path.GetDirectoryName(inList[0].FilePath);
            string fileName = "";

            inList.ForEach(ec => fileName += Path.GetFileNameWithoutExtension(ec.FilePath));
            string filePath = Path.Combine(folder, fileName + ".jpg");

            if (SaveRasteImae(destImage, filePath))
            {
                if (deleteSrcFile)
                {
                    inList.ForEach(ea =>
                    {

                        File.Delete(ea.FilePath);
                    });
                }
                return filePath;
            }
            else
            {
                return "";
            }
        }
        public static string CombinThreeImageFromFile(List<FileSizeInfo> inList, bool deleteSrcFile = true)
        {
            var first = CreateImageWithFlag(inList[0]);
            var seond = CreateImageWithFlag(inList[1]);
            var three = CreateImageWithFlag(inList[2]);

            var destImage = CombineTwoImage(first, seond, 1);
            destImage = CombineTwoImage(destImage, three, 1);
            string folder = Path.GetDirectoryName(inList[0].FilePath);
            string fileName = "";

            inList.ForEach(ec => fileName += Path.GetFileNameWithoutExtension(ec.FilePath));
            string filePath = Path.Combine(folder, fileName + ".jpg");

            if (SaveRasteImae(destImage, filePath))
            {
                if (deleteSrcFile)
                {
                    inList.ForEach(ea =>
                    {

                        File.Delete(ea.FilePath);
                    });
                }
                return filePath;
            }
            else
            {
                return "";
            }
        }
        public static string CombinFourImageFromFile(List<FileSizeInfo> inList, bool deleteSrcFile = true)
        {
            inList = inList.OrderBy(o => o.Width).ToList();
            var first = CreateImageWithFlag(inList[0]);
            var seond = CreateImageWithFlag(inList[1]);
            var three = CreateImageWithFlag(inList[2]);
            var four = CreateImageWithFlag(inList[3]);

            var destImageB = CombineTwoImage(first, seond, 1);
            var destImageT = CombineTwoImage(three, four, 1);
            var destImage = CombineTwoImage(destImageB, destImageT, 0);
            string folder = Path.GetDirectoryName(inList[0].FilePath);
            string fileName = "";

            inList.ForEach(ec => fileName += Path.GetFileNameWithoutExtension(ec.FilePath));
            fileName = fileName.Replace("_", "").Replace("IMG", "").Replace("钱包", "").Replace("钥匙", "");
            if (fileName.Length >= 200)
            {

                fileName = fileName.Substring(100);
            }
            string filePath = Path.Combine(folder, fileName + ".jpg");

            if (SaveRasteImae(destImage, filePath))
            {
                if (deleteSrcFile)
                {
                    inList.ForEach(ea =>
                    {

                        File.Delete(ea.FilePath);
                    });
                }
                return filePath;
            }
            else
            {
                return "";
            }
        }
        private static RasterImage CreateImageWithFlag(FileSizeInfo info)
        {
            FileSizeInfo firstInfo = info;
            RasterImage firstImage = _codecs.Load(firstInfo.FilePath);
            if (firstInfo.IsRoata)
            {
                RotateImage(firstImage, 90);
            }
            var flagImage = GenerateTags(firstInfo.FileName, firstInfo.PixWidth);
            return CombineTwoImage(firstImage, flagImage, 0);
        }
    }


    public class DiBImageInfo
    {
        public DiBImageInfo(int w, int h)
        {
            this.width = w;
            this.heigth = h;
        }

        public int width { get; set; }
        public int heigth { get; set; }
        public IntPtr Ptr { get; set; }
    }

    public class FileSizeInfo
    {
        public FileSizeInfo()
        {
            IsRoata = false;
        }

        public FileSizeInfo(int w, int h, int xdpi, int ydpi, string inPath)
        {
            if (w < h)
            {
                this.PixWidth = w;
                this.PixHeight = h;
                this.XDpi = xdpi;
                this.YDpi = ydpi;
                this.FilePath = inPath;
                this.IsRoata = false;
            }
            else
            {
                this.PixWidth = h;
                this.PixHeight = w;
                this.XDpi = ydpi;
                this.YDpi = xdpi;
                this.FilePath = inPath;
                this.IsRoata = true;
            }
        }

        public decimal Width
        {
            get
            {
                if (XDpi != 0)
                {
                    return PixWidth / (decimal)XDpi;
                }
                else
                {
                    return 0;
                }
            }

        }

        public decimal Heigth
        {
            get
            {
                if (YDpi != 0)
                {
                    return PixHeight / (decimal)YDpi;
                }
                else
                {
                    return 0;
                }
            }

        }
        public int PixWidth { get; set; }
        public int PixHeight { get; set; }
        public string FileName { get; set; }
        public bool IsRoata { get; set; }

        public int XDpi
        {
            get;
            set;
        }

        public int YDpi { get; set; }
        public string FilePath { get; set; }


    }
}
